package com.wxy.ej.flow.modules.taskflow.service.nodeExecuteStrategy.strategy.code;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rt.easyjava.common.base.Result;
import com.rt.easyjava.common.config.SpringContextBaseHolder;
import com.rt.easyjava.common.utils.others.StringUtils;
import com.wxy.ej.flow.modules.taskflow.dto.DataDto;
import com.wxy.ej.flow.modules.taskflow.dto.NodeDto;
import com.wxy.ej.flow.modules.taskflow.repository.JdbcRepository;
import com.wxy.ej.flow.modules.taskflow.service.nodeExecuteStrategy.NodeStrategy;
import com.wxy.ej.flow.utils.RegexUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

@Slf4j
public class CodeSqlCodeNodeStrategy extends NodeStrategy {

    private JdbcRepository jdbcRepository;

    @Override
    public Result action(NodeDto node, JSONObject flowDataJson, DataDto dataDto) throws Exception {
        String sqlScripts = node.getScript();
        String sqlDataVar = node.getDefineVarName();

        // 初始化 sqlDataVar = []
        if (!StringUtils.isNull(sqlDataVar)) {
            dataDto.getStorageDataVarMap().put(sqlDataVar, new ArrayList<>());
        }

        // run sql
        jdbcRepository = SpringContextBaseHolder.getBean("jdbcRepository");
        List<String> sqlList = Arrays.asList(sqlScripts.split(";"));
        for (String sql:sqlList) {
            if (StringUtils.isNull(sql)) {
                continue;
            }
            log.info(sql);
            sql = sql.trim();

            // 正则从sql script中, 取${item.id}
            String pattern = "\\$\\{[\\w.}\\[\\]]*";
            List<String> jsScriptList = RegexUtils.searchMatch(sql, pattern,0);
            System.out.println(jsScriptList);

            // 执行js取值
            System.out.println("=====> jsResultMap");
            Map<String, Object> jsResultMap = new HashMap<>();
            for (String jsScript:jsScriptList) {
                System.out.println(jsScript);
                String jsScript2 = jsScript.substring(2, jsScript.length()-1);
                Object o = executeScriptForResult(dataDto, jsScript2);
                jsResultMap.put(jsScript, o);
            }
            System.out.println(jsResultMap);

            // replace sql script
            List<Object> paramList = new ArrayList<>();
            for (String key:jsScriptList) {
                sql = sql.replace(key, "?");
                if (jsResultMap.get(key)==null) {
                    paramList.add(null);
                }else {
                    paramList.add(jsResultMap.get(key).toString());
                }
            }

            dataDto.getLogList().add(sql);
            dataDto.getLogList().add(JSONArray.toJSONString(paramList));
            Object sqlResult;
            if (sql.toLowerCase().startsWith("select")) {
                // 返回结果集
                sqlResult = jdbcRepository.executeQuery(sql, paramList);
            }else if (sql.toLowerCase().startsWith("insert")){
                // 返回主键
                sqlResult = jdbcRepository.executeInsert(sql, paramList);
            }else{
                sqlResult = jdbcRepository.executeUpdate(sql, paramList);
            }

            // 存入执行的数据
            if (StringUtils.isNull(sqlResult)) {
                sqlResult = 0;
            }
            if (!StringUtils.isNull(sqlDataVar)) {
                List sqlDataList = (List) dataDto.getStorageDataVarMap().get(sqlDataVar);
                sqlDataList.add(sqlResult);
                //dataDto.getStorageDataVarMap().put(sqlDataVar, sqlDataList);
            }
        }

        // 打印日志
        boolean isPrintLog = node.getIsPrintLog()==null?false:node.getIsPrintLog().booleanValue();
        if (isPrintLog) {
            if (!StringUtils.isNull(sqlDataVar)) {
                List sqlDataList = (List) dataDto.getStorageDataVarMap().get(sqlDataVar);
                String sqlDataListJsonString = JSONArray.toJSONString(sqlDataList);
                dataDto.getLogList().add(sqlDataListJsonString);
            }
        }

        return Result.builder();
    }


}
